﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows;
using System.Globalization;

namespace MockupDesigner.AppItems.Commands
{
    public class PasteCommand : ICommand
    {

        public CommandType CommandType
        {
            get { return CommandType.Undoable; }
        }

        private XElement rootElement;
        private IList<ISelectable> newItems;

        private DesignerCanvas designerCanvas;

        public void Execute(object target, params object[] parameters)
        {
            if (!(target is DesignerCanvas))
            {
                throw new InvalidCastException("The target must be a DesignerCanvas");
            }
            this.designerCanvas = (DesignerCanvas)target;

            Redo();
        }

        public void Redo()
        {
            if (rootElement == null)
                rootElement = this.designerCanvas.SerializationService.LoadSerializedDataFromClipBoard();

            if (rootElement == null)
                return;

            // create DesignerItems
            Dictionary<Guid, Guid> mappingOldToNewIDs = new Dictionary<Guid, Guid>();
            IEnumerable<XElement> itemsXML = rootElement.Elements("DesignerItems").Elements("DesignerItem");

            double offsetX = Double.Parse(rootElement.Attribute("OffsetX").Value, CultureInfo.InvariantCulture);
            double offsetY = Double.Parse(rootElement.Attribute("OffsetY").Value, CultureInfo.InvariantCulture);
            newItems = new List<ISelectable>();
            foreach (XElement itemXML in itemsXML)
            {
                Guid oldID = new Guid(itemXML.Element("ID").Value);
                Guid newID = Guid.NewGuid();
                mappingOldToNewIDs.Add(oldID, newID);
                DesignerItem item = DocumentSerializationService.DeserializeDesignerItem(itemXML, newID, offsetX, offsetY);
                if (item != null)
                {
                    this.designerCanvas.Children.Add(item);
                    newItems.Add(item);
                }
            }

            // update group hierarchy
            this.designerCanvas.SelectionService.ClearSelection();
            foreach (DesignerItem el in newItems)
            {
                if (el.ParentID != Guid.Empty)
                    el.ParentID = mappingOldToNewIDs[el.ParentID];
            }


            foreach (DesignerItem item in newItems)
            {
                if (item.ParentID == Guid.Empty)
                {
                    this.designerCanvas.SelectionService.AddToSelection(item);
                }
            }
            ToBackFrontCommand bringCommand = new ToBackFrontCommand();
            bringCommand.Execute(this.designerCanvas, OppositeType.ToFront);

            // update paste offset
            rootElement.Attribute("OffsetX").Value = (offsetX + 10).ToString();
            rootElement.Attribute("OffsetY").Value = (offsetY + 10).ToString();
            Clipboard.Clear();
            Clipboard.SetData(DataFormats.Xaml, rootElement);
        }

        public void Undo()
        {
            foreach (ISelectable item in newItems)
            {
                if (item is DesignerItem)
                {
                    this.designerCanvas.Children.Remove(item as DesignerItem);
                }
            }
        }

    }
}
